#include "MapCanvasItem.h"
#include "MapCanvas.h"
#include "MapRenderer.h"
#include <TGS/MapControl2.0/MapToPixel.h>
#include <TGS/MapControl2.0/RenderContext.h>
#include <QGraphicsScene>
#include <QRect>
#include <QPen>
#include <QBrush>
#include <QPainter>

namespace TGS{
namespace MapControl{

MapCanvasItem::MapCanvasItem( MapCanvas* mapCanvas )
    : QGraphicsItem(nullptr, mapCanvas->scene() )
	, _mapCanvas( mapCanvas )
	, _panningOffset( 0, 0 )
	, _itemSize( 0, 0 )
{
}

MapCanvasItem::~MapCanvasItem()
{
	update(); // schedule redraw of canvas
}

void MapCanvasItem::paint( QPainter * painter,
                              const QStyleOptionGraphicsItem * option,
                              QWidget * widget )
{
	Q_UNUSED( option );
	Q_UNUSED( widget );
	if ( _mapCanvas->antiAliasingEnabled() )
	{
		painter->setRenderHint( QPainter::Antialiasing );
	}
	paint( painter ); // call the derived item's drawing routines
}

MapCanvasItem::Point MapCanvasItem::toMapCoordinates( const QPoint& point )
{
	return _mapCanvas->getCoordinateTransform()->screenToMap( point - _panningOffset );
}


QPointF MapCanvasItem::toCanvasCoordinates( const Point& point )
{
	double x = point.getX(), y = point.getY();
	QPoint pt = _mapCanvas->getCoordinateTransform()->mapToScreen( x, y );
	return QPointF( pt.x(), pt.y() ) + _panningOffset;
}


MapCanvasItem::Envelope MapCanvasItem::rect() const
{
	return _rect;
}


void MapCanvasItem::setRect( const Envelope& rect )
{
	_rect = rect;
	//updatePosition();

	QRectF r; // empty rect by default
	if ( !_rect.isEmpty() )
	{
		r.setTopLeft( toCanvasCoordinates( Point( _rect.getMinX(), _rect.getMinY() ) ) );
		r.setBottomRight( toCanvasCoordinates(Point( _rect.getMaxX(), _rect.getMaxY() ) ) );
		r = r.normalized();
	}

	// set position in canvas where the item will have coordinate (0,0)
	prepareGeometryChange();
	setPos( r.topLeft() );
	_itemSize = QSizeF( r.width() + 2, r.height() + 2 );

	update();
}

QRectF MapCanvasItem::boundingRect() const
{
	return QRectF( QPointF( -1, -1 ), _itemSize );
}


void MapCanvasItem::updateCanvas()
{
	update();
  // porting: update below should not be needed anymore
  //mMapCanvas->scene()->update(); //Contents();
}

bool MapCanvasItem::setRenderContextVariables( QPainter* p, RenderContext& context ) const
{
	if ( !_mapCanvas || !p )
	{
		return false;
	}
	MapRenderer* mapRenderer = _mapCanvas->mapRenderer();
	if ( !mapRenderer )
	{
		return false;
	}

	context.setPainter( p );
	context.setRendererScale( _mapCanvas->scale() );

	int dpi = mapRenderer->outputDpi();
	int painterDpi = p->device()->logicalDpiX();
	double scaleFactor = 1.0;
	double rasterScaleFactor = 1.0;

	//little trick to find out if painting origines from composer or main map canvas
	if ( data( 1 ).toString() == "composer" )
	{
		rasterScaleFactor = painterDpi / 25.4;
		scaleFactor = dpi / 25.4;
	}
	else
	{
		if ( mapRenderer->outputUnits() == MapRenderer::Millimeters )
		{
			scaleFactor = dpi / 25.4;
		}
	}
	context.setScaleFactor( scaleFactor );
	context.setRasterScaleFactor( rasterScaleFactor );
	return true;
}

void MapCanvasItem::updatePosition()
{
  // default implementation: recalculate position of the item
	setRect( _rect );
}


void MapCanvasItem::setPanningOffset( const QPoint& point )
{
	_panningOffset = point;
}


}//MapControl
}//TGS